package cn.dgut.training.service.impl;

import cn.dgut.training.controller.ActivityService;
import cn.dgut.training.controller.UserService;
import cn.dgut.training.dto.goods.CartUpdateDTO;
import cn.dgut.training.e.Status;
import cn.dgut.training.emun.CartCheckedEnum;
import cn.dgut.training.dto.goods.CartDTO;
import cn.dgut.training.entity.activity.Coupon;
import cn.dgut.training.entity.activity.CouponUser;
import cn.dgut.training.entity.activity.GroupBuying;
import cn.dgut.training.entity.goods.Cart;
import cn.dgut.training.entity.goods.Goods;
import cn.dgut.training.entity.goods.GoodsProduct;
import cn.dgut.training.entity.user.Address;
import cn.dgut.training.mapper.GoodsProductMapper;
import cn.dgut.training.vo.goods.CartListVO;
import cn.dgut.training.vo.goods.CartTotal;
import cn.dgut.training.dto.transaction.Checkout;
import cn.dgut.training.dto.transaction.OrdersDTO;
import cn.dgut.training.mapper.CartMapper;
import cn.dgut.training.mapper.GoodsMapper;
import cn.dgut.training.service.ICartService;
import cn.dgut.training.vo.CommonResponse;
import cn.dgut.training.vo.goods.CheckoutVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {

    @Resource
    private CartMapper cartMapper;

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private GoodsProductMapper goodsProductMapper;

    @Autowired
    private UserService userService;

    @Resource
    private ActivityService activityService;

    @Override
    public CartListVO index(Long userID) {
        CartListVO cartListVO = new CartListVO();

        //得到商品列表
        List<Cart> cartList = cartMapper.selectList(new QueryWrapper<Cart>().lambda().eq(Cart::getUserId, userID));

        //删除不存在的或者下架的商品
        for (Cart cart : cartList) {
            Goods goods = goodsMapper.selectById(cart.getGoodsId());
            GoodsProduct goodsProduct = goodsProductMapper.selectById(cart.getProductId());
            if (goods == null || goods.getIsOnSale().equals(false) || goodsProduct == null) {
                cartMapper.deleteById(cart);
            }
        }

        //计算购物车的价格等信息
        CartTotal cartTotal = new CartTotal();
        for (Cart cart : cartList) {
            cartTotal.setGoodsCount(cartTotal.getGoodsCount() + cart.getProductNumber());
            cartTotal.setGoodsAmount(cartTotal.getGoodsAmount().add(cart.getPrice().multiply(new BigDecimal(cart.getProductNumber()))));
            if (cart.getChecked().equals(CartCheckedEnum.IS_CHECKED.getValue())) {
                cartTotal.setCheckedGoodsCount(cartTotal.getCheckedGoodsCount() + cart.getProductNumber());
                cartTotal.setCheckedGoodsAmount(cartTotal.getCheckedGoodsAmount().add(cart.getPrice().multiply(new BigDecimal(cart.getProductNumber()))));
            }
        }

        cartListVO.setCartList(cartList);
        cartListVO.setCartTotal(cartTotal);
        return cartListVO;
    }

    @Override
    public CommonResponse addGoods(CartDTO cartDTO) {
        Goods goods = goodsMapper.selectById(cartDTO.getGoodsId());
        GoodsProduct goodsProduct = goodsProductMapper.selectById(cartDTO.getProductId());

        //判断商品是否下架
        if (goods == null || !goods.getIsOnSale() || goodsProduct == null) {
            return CommonResponse.fail(Status.GOODS_UNSHELVE.getCode(), Status.GOODS_UNSHELVE.getMessage());
        }

        Cart existCart = cartMapper.selectOne(new QueryWrapper<Cart>().lambda()
                .eq(Cart::getGoodsId, cartDTO.getGoodsId())
                .eq(Cart::getUserId, cartDTO.getUserId())
                .eq(Cart::getProductId, cartDTO.getProductId()));

        //当购物车不存在该商品时
        if (existCart == null) {

            //判断商品库存是否够
            if (cartDTO.getProductNumber() > goodsProduct.getStock()) {
                return CommonResponse.fail(Status.GOODS_NO_STOCK.getCode(), Status.GOODS_NO_STOCK.getMessage());
            }
            //将该购物车商品入库
            Cart cart = new Cart();
            String picUrl = null;
            if (StringUtils.isNoneBlank(goodsProduct.getUrl())) {
                picUrl = goodsProduct.getUrl();
            } else {
                picUrl = goods.getPicUrl();
            }
            cart.setGoodsId(goods.getId()).setGoodsName(goods.getName()).setGoodsSn(goods.getGoodsSn()).setProductNumber(cartDTO.getProductNumber())
                    .setPicUrl(picUrl).setUserId(cartDTO.getUserId()).setProductId(cartDTO.getProductId())
                    .setPrice(goodsProduct.getPrice()).setChecked(true).setSpecifications(cartDTO.getSpecifications());
            cartMapper.insert(cart);
        } else {
            //判断商品库存是否够
            if (cartDTO.getProductNumber() > goodsProduct.getStock()) {
                return CommonResponse.fail(Status.GOODS_NO_STOCK.getCode(), Status.GOODS_NO_STOCK.getMessage());
            }
            //更新该购物车商品
            existCart.setProductNumber(existCart.getProductNumber() + cartDTO.getProductNumber());
            cartMapper.updateById(existCart);
        }
        return CommonResponse.success(goodCount(cartDTO.getUserId()));
    }

    @Override
    public CommonResponse fastAdd(CartDTO cartDTO) {
        Goods goods = goodsMapper.selectById(cartDTO.getGoodsId());
        Cart cart = new Cart();
        GoodsProduct goodsProduct = goodsProductMapper.selectById(cartDTO.getProductId());

        //判断商品是否下架
        if (goods == null || !goods.getIsOnSale() || goodsProduct == null) {
            return CommonResponse.fail(Status.GOODS_UNSHELVE.getCode(), Status.GOODS_UNSHELVE.getMessage());
        }

        Cart existCart = cartMapper.selectOne(new QueryWrapper<Cart>().lambda()
                .eq(Cart::getGoodsId, cartDTO.getGoodsId())
                .eq(Cart::getUserId, cartDTO.getUserId())
                .eq(Cart::getProductId, cartDTO.getProductId()));

        //当购物车不存在该商品时
        if (existCart == null) {

            //判断商品库存是否够
            if (cartDTO.getProductNumber() > goodsProduct.getStock()) {
                return CommonResponse.fail(Status.GOODS_NO_STOCK.getCode(), Status.GOODS_NO_STOCK.getMessage());
            }
            String picUrl = null;
            if (StringUtils.isNoneBlank(goodsProduct.getUrl())) {
                picUrl = goodsProduct.getUrl();
            } else {
                picUrl = goods.getPicUrl();
            }

            //将该购物车商品入库
            cart.setGoodsId(goods.getId()).setGoodsName(goods.getName()).setGoodsSn(goods.getGoodsSn()).setProductNumber(cartDTO.getProductNumber())
                    .setPicUrl(picUrl).setUserId(cartDTO.getUserId()).setProductId(cartDTO.getProductId())
                    .setPrice(goodsProduct.getPrice()).setChecked(true).setSpecifications(cartDTO.getSpecifications());
            cartMapper.insert(cart);
        } else {
            //判断商品库存是否够
            if (cartDTO.getProductNumber() > goodsProduct.getStock()) {
                return CommonResponse.fail(Status.GOODS_NO_STOCK.getCode(), Status.GOODS_NO_STOCK.getMessage());
            }
            //将新商品数量覆盖购物车中原该商品的数量
            existCart.setProductNumber(cartDTO.getProductNumber());
            cartMapper.updateById(existCart);
        }
        return CommonResponse.success(existCart != null ? existCart.getId() : cart.getId());

    }

    @Override
    public Long checked(CartUpdateDTO cartUpdateDTO) {
        List<Cart> cartList = new ArrayList<>();
        for (Long productId : cartUpdateDTO.getProductIds()) {
            Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>().lambda().eq(Cart::getProductId, productId)
                    .eq(Cart::getUserId, cartUpdateDTO.getUserId()));
            cart.setChecked(cartUpdateDTO.getIsChecked());
            cartMapper.updateById(cart);
        }
        return cartUpdateDTO.getUserId();
    }

    @Override
    public CommonResponse updateGoods(CartDTO cartDTO) {
        Goods goods = goodsMapper.selectById(cartDTO.getGoodsId());
        GoodsProduct goodsProduct = goodsProductMapper.selectById(cartDTO.getProductId());
        //判断商品是否下架
        if (goods == null || !goods.getIsOnSale() || goodsProduct == null) {
            return CommonResponse.fail(Status.GOODS_UNSHELVE.getCode(), Status.GOODS_UNSHELVE.getMessage());
        }
        //判断商品库存是否够
        if (cartDTO.getProductNumber() > goodsProduct.getStock()) {
            return CommonResponse.fail(Status.GOODS_NO_STOCK.getCode(), Status.GOODS_NO_STOCK.getMessage());
        }
        Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>().lambda().eq(Cart::getUserId, cartDTO.getUserId())
                .eq(Cart::getGoodsId, cartDTO.getGoodsId())
                .eq(Cart::getProductId, cartDTO.getProductId()));
        cart.setProductNumber(cartDTO.getProductNumber());
        cartMapper.updateById(cart);
        return CommonResponse.message();
    }

    @Override
    public Long deleteGoods(CartDTO cartDTO) {
        List<Long> productIdList = cartDTO.getProductIds();
        for (Long productId : productIdList) {
            Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>().lambda()
                    .eq(Cart::getUserId, cartDTO.getUserId())
                    .eq(Cart::getProductId, productId));
            cartMapper.deleteById(cart);
        }
        return cartDTO.getUserId();
    }

    @Override
    @Transactional
    public CommonResponse checkout(Long userId, Checkout checkout) {
        if (userId == null) {
            return CommonResponse.fail(Status.NOT_LOGGED_IN.getCode(), Status.NOT_LOGGED_IN.getMessage());
        }
        CheckoutVO checkoutVO = new CheckoutVO();
        //收货地址 gia
        Address checkedAddress = null;
        Long checkedAddressId = checkout.getAddressId();
        if (checkedAddressId == null || checkedAddressId.equals(0L)) {
            checkedAddress = userService.iShowDefaultAddress(userId);
            // 如果仍然没有地址，则是没有收货地址
            // 返回一个空的地址id=0，这样前端则会提醒添加地址
            if (checkedAddress == null) {
                checkedAddress = new Address();
                checkedAddress.setId(0L);
                checkedAddressId = 0L;
            } else {
                checkedAddressId = checkedAddress.getId();
            }

        } else {
            checkedAddress = userService.iGetById(checkedAddressId);
            if (checkedAddress == null) {
                return CommonResponse.fail();
            }
        }

        //团购优惠 giao
        BigDecimal groupBuyingPrice = new BigDecimal(0.00);
        if (checkout.getGrouponLinkId() != null) {
            GroupBuying groupBuying = activityService.iGetById(checkout.getGrouponLinkId());
            if (groupBuying != null&&groupBuying.getStatus()==0) {
                groupBuyingPrice = groupBuying.getDiscount();
            }
        }

        //商品价格
        List<Cart> cartList = new ArrayList<>();
        if (checkout.getCartId() == null || checkout.getCartId().equals(0L)) {
            cartList = cartMapper.selectList(new QueryWrapper<Cart>()
                    .lambda()
                    .eq(Cart::getUserId, userId)
                    .eq(Cart::getChecked, CartCheckedEnum.IS_CHECKED.getValue()));

        } else {
            Cart fastAddCart = cartMapper.selectById(checkout.getCartId());
            if (fastAddCart == null) {
                return CommonResponse.fail(Status.GOODS_UNSHELVE.getCode(), Status.GOODS_UNSHELVE.getMessage());
            }
            cartList.add(fastAddCart);
        }
        BigDecimal checkoutGoodsPrice = new BigDecimal(0.00);
        for (Cart cart : cartList) {
            //符合团购id的商品才能优惠 giao

            checkoutGoodsPrice = checkoutGoodsPrice.add(cart.getPrice().multiply(new BigDecimal(cart.getProductNumber())));
        }

        //得到优惠券信息 giao
        BigDecimal tmpCouponPrice = new BigDecimal(0.00);
        Long tmpCouponId = -1L;
        Long tmpUserCouponId = null;
        Integer tmpCouponLength = 0;
        List<CouponUser> couponUserList = activityService.listAllByUser(userId);
        for (CouponUser couponUser : couponUserList) {
            tmpCouponId = couponUser.getCouponId();
            Coupon coupon = activityService.accordWith(tmpCouponId, checkoutGoodsPrice);
            if (coupon == null) {
                continue;
            }
            tmpCouponLength++;
            if (tmpCouponPrice.compareTo(coupon.getAmount()) < 0) {
                tmpCouponPrice = coupon.getAmount();
                tmpCouponId = coupon.getId();
            }
        }
        // 获取优惠券减免金额，优惠券可用数量
        int availableCouponLength = tmpCouponLength;
        BigDecimal couponPrice = new BigDecimal(0);
        Long couponId = 0L;
        if (checkout.getCouponId() != null) {
            couponId = checkout.getCouponId();
        }
        Long userCouponId = checkout.getUserCouponId();
        // 这里存在三种情况
        // 1. 用户不想使用优惠券，则不处理 -1
        // 2. 用户想自动使用优惠券，则选择合适优惠券 （上方）
        // 3. 用户已选择优惠券，则测试优惠券是否合适
        if (couponId == null || couponId.equals(-1L)) {
            couponId = -1L;
            userCouponId = -1L;
        } else if (couponId.equals(0L)) {
            couponPrice = tmpCouponPrice;
            couponId = tmpCouponId;
            userCouponId = tmpUserCouponId;
        } else {
            Coupon coupon = activityService.accordWith(tmpCouponId, checkoutGoodsPrice);
            // 用户选择的优惠券有问题，则选择合适优惠券，否则使用用户选择的优惠券
            if (coupon == null) {
                couponPrice = tmpCouponPrice;
                couponId = tmpCouponId;
                userCouponId = tmpUserCouponId;
            } else {
                couponPrice = coupon.getAmount();
            }
        }


        //计算价格
        BigDecimal freightPrice = new BigDecimal(0.00);
        BigDecimal orderTotalPrice = new BigDecimal(0.00);
        BigDecimal integralPrice = new BigDecimal(0.00);
        if (checkoutGoodsPrice.compareTo(new BigDecimal(88)) < 0) {
            freightPrice = new BigDecimal(8.00);
            orderTotalPrice = checkoutGoodsPrice.add(freightPrice);
        } else {
            orderTotalPrice = checkoutGoodsPrice;
        }
        BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice).subtract(groupBuyingPrice).subtract(couponPrice);

        //返回给前端
        checkoutVO.setActualPrice(actualPrice);
        checkoutVO.setAddressId(checkedAddressId);
        checkoutVO.setCartId(checkout.getCartId());
        checkoutVO.setCheckedAddress(checkedAddress);
        checkoutVO.setCheckedGoodsList(cartList);
        checkoutVO.setCouponId(couponId);
        checkoutVO.setCheckedGoodsPrice(checkoutGoodsPrice);
        checkoutVO.setActualPrice(actualPrice);
        checkoutVO.setCouponPrice(couponPrice);
        checkoutVO.setAvailableCouponLength(availableCouponLength);
        checkoutVO.setFreightPrice(freightPrice);
        checkoutVO.setGrouponPrice(groupBuyingPrice);
        checkoutVO.setUserCouponId(userCouponId);
        checkoutVO.setOrderTotalPrice(orderTotalPrice);
        checkoutVO.setGrouponLinkId(checkout.getGrouponLinkId());
        checkoutVO.setGrouponRulesId(checkout.getGrouonRulesId());
        return CommonResponse.success(checkoutVO);
    }

    public CommonResponse goodCount(Long userId) {
        if (userId == null) {
            return CommonResponse.fail(Status.NOT_LOGGED_IN.getCode(), Status.NOT_LOGGED_IN.getMessage());
        }
        Integer goodCount = cartMapper.selectCount(new QueryWrapper<Cart>().lambda().eq(Cart::getUserId, userId));
        return CommonResponse.success(goodCount);
    }

    @Override
    public void updateByGoodsProduct(GoodsProduct goodsProduct, Goods goods) {

        List<Cart> cart = cartMapper.selectList(new QueryWrapper<Cart>().eq("product_id", goodsProduct.getId()));

        for (Cart c : cart) {
            c.setGoodsName(goods.getName());
            c.setPrice(goodsProduct.getPrice());
            c.setProductNumber(goodsProduct.getStock());
            c.setPicUrl(goodsProduct.getUrl());
            cartMapper.updateById(c);
        }


    }
}
